package com.xpec.c4.persistence;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * 数据分析器，完成游戏数据的XML持久化转换<br>
 * 可分析的类型有：1、基本类型(primitive)；2、容器类型(collection)；3、自定义类型(complex)
 * 
 * @author Magmaster
 *
 */
public class XMLParser implements IParser
{
	private static final Log log = LogFactory.getLog(XMLParser.class);
	
	public static final String FIELD_TYPE_PRIMITIVE = "primitive";
	public static final String FIELD_TYPE_COLLECTION = "collection";
	public static final String FIELD_TYPE_COMPLEX = "complex";
	
	
	public static final String COLLECTION_TYPE_UNARY = "1";
	public static final String COLLECTION_TYPE_BINARY= "2";
	
	
	private Object createObject(String strClass, String strValue)
				throws Exception
	{
		Object obj = null;
		
		Class<?> c = Class.forName(strClass);
		//System.out.println("Parse: class - " + strClass + "; value - " + strValue);
		if(c.isEnum())
		{
			Object [] enumValues = c.getEnumConstants();
			for(int i=0; i<enumValues.length; i++)
			{
				if(enumValues[i].toString().equals(strValue))
				{
					obj = enumValues[i];
					break;
				}
			}
			
		}
		else if (c.equals(Character.class))	//Character没有String为参数的构造函数
		{
			Constructor<?> cst = c.getConstructor(char.class);
			obj = cst.newInstance(strValue.charAt(0));
		}
		else
		{
			Constructor<?> cst = c.getConstructor(java.lang.String.class);	//以String为参数的构造函数
			obj = cst.newInstance(strValue);
		}
		
		return obj;
	}
	
	private Object buildPrimitive(Object src, Strategy stg,HashMap<String, Object> context, Field field)
	{
		Element element = null;
		try
		{
			field.setAccessible(true);
			
			Document doc = (Document)context.get("xml_document");
		
			element = doc.createElement("Field");
			element.setAttribute("name", field.getName());
			element.setAttribute("class", field.getType().getName());
			element.setAttribute("value", field.get(src).toString());
			
			field.setAccessible(false);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return element;
	}
	
	private Object buildCollection(Object src, Strategy stg, HashMap<String, Object> context, Field field)
	{
		Element element = null;
		try
		{
			field.setAccessible(true);
			
			Document doc = (Document)context.get("xml_document");
			element = doc.createElement("Field");
			element.setAttribute("name", field.getName());
			element.setAttribute("class", field.getType().getName());
			
			String dimension = stg.getFieldConfig(field.getName(), "dimension");	//一元容器还是二元容器
			boolean isValueFW = "yes".equals(stg.getFieldConfig(field.getName(), "value_flyweight"));
			
			if(COLLECTION_TYPE_UNARY.equals(dimension))	//一元容器
			{
				String value_type = stg.getFieldConfig(field.getName(), "value_type");
				Object objField = field.get(src);
				
				Object values = null;
				
				if(objField instanceof java.util.Collection)	//一元容器
				{
					Collection<?> collection = (Collection<?>)objField;
					values = collection.toArray();
				}
				else	//数组
				{
					values = objField;
				}
				
				
				if(values != null)
				{
					int length = Array.getLength(values);
					element.setAttribute("length", String.valueOf(length));
					
					String strCellClass;
					
					//一元容器的元素只允许primitive和complex，不支持collection
					for(int j=0; j<length; j++)
					{
						Object v = Array.get(values, j);
						if(v == null) continue;
						
						strCellClass = v.getClass().getName();
						
						Element element_cell = doc.createElement("cell");
						element_cell.setAttribute("index", String.valueOf(j));
						element_cell.setAttribute("class", strCellClass);
				
						if(FIELD_TYPE_PRIMITIVE.equals(value_type))
						{
							element_cell.setAttribute("value", v.toString());
						}
						else if(FIELD_TYPE_COMPLEX.equals(value_type))
						{
							if(isValueFW)	//享元只存储id
							{
								Method method = v.getClass().getMethod("getId");
								if(method != null)
								{
									element_cell.setAttribute("objId", method.invoke(v).toString());
								}
							}
							else			//非享元存储完整对象
							{
								Strategy cellStg = PersistenceManager.getInstance().getStrategy(v.getClass().getName());
								if(cellStg != null)
								{
									IParser parser = PersistenceManager.getInstance().getParser(cellStg.parser);
									if(parser != null)
									{
										element_cell.appendChild((Node)parser.build(v, context));
									}
								}
							}
						}
						
						element.appendChild(element_cell);
					}
				}
			}
			else if(COLLECTION_TYPE_BINARY.equals(dimension))	//二元容器
			{
				String key_type = stg.getFieldConfig(field.getName(), "key_type");
				String value_type = stg.getFieldConfig(field.getName(), "value_type");
				
				Map<?, ?> map = (Map<?, ?>)field.get(src);
				Object [] keys = map.keySet().toArray();
				
				//二元容器的关键字(key1)只支持primitive，值(value)只支持primitive和complex
				for(int j=0; j<keys.length; j++)
				{
					if(FIELD_TYPE_PRIMITIVE.equals(key_type))
					{
						Element element_cell = doc.createElement("cell");
						element_cell.setAttribute("key", keys[j].toString());
						element_cell.setAttribute("key_class", keys[j].getClass().getName());
						if(map.get(keys[j]) != null)
						{
							element_cell.setAttribute("value_class", map.get(keys[j]).getClass().getName());
						}

						if(FIELD_TYPE_PRIMITIVE.equals(value_type))
						{
							element_cell.setAttribute("value", map.get(keys[j]).toString());
						}
						else if(FIELD_TYPE_COMPLEX.equals(value_type))
						{
							Object objValue = map.get(keys[j]);
							if(objValue != null)
							{
								if(isValueFW)	//享元只存储id
								{
									Method method = objValue.getClass().getMethod("getId");
									if(method != null)
									{
										element_cell.setAttribute("objId", method.invoke(objValue).toString());
									}

								}
								else			//非享元存储完整对象
								{
									Strategy cellStg = PersistenceManager.getInstance().getStrategy(objValue.getClass().getName());
									if(cellStg != null)
									{
										IParser parser = PersistenceManager.getInstance().getParser(cellStg.parser);
										if(parser != null)
										{
											element_cell.appendChild((Node)parser.build(map.get(keys[j]), context));
										}
									}
								}
							}
						}
						element.appendChild(element_cell);
					}
				}
			}
			
			field.setAccessible(false);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return element;
	}
	
	private Object buildComplex(Object src, Strategy stg, HashMap<String, Object> context, Field field)
	{
		Element element = null;
		try
		{
			field.setAccessible(true);
			
			Document doc = (Document)context.get("xml_document");
			element = doc.createElement("Field");
			element.setAttribute("name", field.getName());
			
			boolean isFlyWeight = "yes".equals(stg.getFieldConfig(field.getName(), "flyweight"));
			
			Object fieldObj = field.get(src);
			
			if(fieldObj == null)
			{
				element.setAttribute("class", field.getType().getName());
			}
			else
			{
				if(isFlyWeight)
				{
					element.setAttribute("class", fieldObj.getClass().getName());
					Method method = fieldObj.getClass().getMethod("getId");
					if(method != null)
						element.setAttribute("objId", method.invoke(fieldObj).toString());
				}
				else
				{
					Strategy fieldStg = PersistenceManager.getInstance().getStrategy(
							fieldObj.getClass().getName());
					if(fieldStg != null)
					{
						IParser parser = PersistenceManager.getInstance().getParser(fieldStg.parser);
						if(parser != null)
						{
							element.setAttribute("class", fieldObj.getClass().getName());
							element.appendChild((Node)parser.build(fieldObj, context));
						}
					}
				}
			}
				
			field.setAccessible(false);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return element;
	}
	
	
	/**
	 * 实现IParser的方法，把给定的对象转换为持久化数据
	 * @param src		待转换对象
	 * @param context	上下文环境，在根部调用时需要传入null
	 * @return			持久化数据
	 */
	public Object build(Object src, HashMap<String, Object> context)
	{
		if(src == null) return null;
		
		//首先获取持久化策略
		Strategy stg = PersistenceManager.getInstance().getStrategy(src.getClass().getName());
		if(stg == null || !stg.parser.equals(this.getClass().getName())) return null;
		
		//根节点，创建上下文环境
		if(context == null)
		{
			context = new HashMap<String, Object>();
			
			try
			{
				Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
				context.put("xml_document", doc);
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		
		Document doc = (Document)context.get("xml_document");
		Element root = doc.createElement("Object");
		root.setAttribute("class", stg.target);
		
		//根据stg中对于src属性的设定生成合适的持久化数据
		String [] fieldNames = stg.getFields();
		if(fieldNames != null)
		{
			for(int i=0; i<fieldNames.length; i++)
			{
				String name = stg.getFieldConfig(fieldNames[i], "name");
				String type = stg.getFieldConfig(fieldNames[i], "type");
				if(name == null || "".equals(name) || type == null || "".equals(type)) continue;
				
				try
				{
					Field field = PersistenceManager.getField(src.getClass(), name);
					if(field == null) continue;
					if(FIELD_TYPE_PRIMITIVE.equals(type))
					{
						root.appendChild((Element)this.buildPrimitive(src, stg, context, field));
					}
					else if(FIELD_TYPE_COLLECTION.equals(type))
					{
						root.appendChild((Element)this.buildCollection(src, stg, context, field));
					}
					else if(FIELD_TYPE_COMPLEX.equals(type))
					{
						root.appendChild((Element)this.buildComplex(src, stg, context, field));
					}
					else
					{
						continue;
					}
				}
				catch(Exception e)
				{
					e.printStackTrace();
				}
			}
		}
		
		return root;
	}
	
	/**
	 * 实现IParser的接口，把给定的数据转化为对象
	 * @param objToFillIn	待填充对象，如果不为null，则会将数据填充到objToFillIn中
	 * @param data		持久化数据
	 * @param context	上下文环境
	 * @return			根据持久化数据生成的对象
	 */
	public Object parse(Object objToFillIn, Object data, HashMap<String, Object> context)
	{
		if(!(data instanceof org.w3c.dom.Element)) return null;
		
		Element root = (Element)data;
		Object result = null;
		
		try
		{
			//result = Class.forName(root.getAttribute("class")).newInstance();
			String lClassName = root.getAttribute("class");
			Class lClass = Class.forName(lClassName);
			//判断是不是传进了要填充的对象
			if (objToFillIn != null && objToFillIn.getClass().getName().equals(lClassName))
			{
				result = objToFillIn;
				this.fillObj(root, result, context);
			}
			else
			{
				//判断是不是singleton的
				try
				{
					Method md = lClass.getDeclaredMethod("getInstance");
					result = md.invoke(null);
					this.fillObj(root, result, context);
				}
				catch(NoSuchMethodException e)
				{
					Constructor lConstructor = lClass.getDeclaredConstructor();
					lConstructor.setAccessible(true);
					result = lConstructor.newInstance();
					lConstructor.setAccessible(false);
					this.fillObj(root, result, context);
				}
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
		return result;
	}
	
	
	private void fillObjPrimitive(Element eField, Object obj, HashMap<String, Object> context)
	{
		try
		{
			Field field = PersistenceManager.getField(obj.getClass(), eField.getAttribute("name"));
			field.setAccessible(true);
			
			String type = eField.getAttribute("class");
			String value = eField.getAttribute("value");
			if(type == null || value == null) return;
			
			if("int".equals(type))
			{
				field.setInt(obj, Integer.parseInt(value));
			}
			else if("java.lang.String".equals(type))
			{
				field.set(obj, value);
			}
			else if("char".equals(type))
			{
				field.setChar(obj, value.charAt(0));
			}
			else if("byte".equals(type))
			{
				field.setByte(obj, Byte.parseByte(value));
			}
			else if("short".equals(type))
			{
				field.setShort(obj, Short.parseShort(value));
			}
			else if("long".equals(type))
			{
				field.setLong(obj, Long.parseLong(value));
			}
			else if("float".equals(type))
			{
				field.setFloat(obj, Float.parseFloat(value));
			}
			else if("double".equals(type))
			{
				field.setDouble(obj, Double.parseDouble(value));
			}
			else if("boolean".equals(type))
			{
				field.setBoolean(obj, Boolean.parseBoolean(value));
			}
			else
			{
				Object objValue = this.createObject(type, value);
				
				field.set(obj, objValue);
				
				/*Class<?> c = Class.forName(type);
				if(c.isEnum())
				{
					Object [] enumValues = c.getEnumConstants();
					for(int i=0; i<enumValues.length; i++)
					{
						if(enumValues[i].toString().equals(value))
						{
							field.set(obj, enumValues[i]);
							break;
						}
					}
					
				}
				else
				{
					Constructor<?> cst = c.getConstructor(java.lang.String.class);	//以String为参数的构造函数
					Object objValue = cst.newInstance(value);
					
					field.set(obj, objValue);
				}*/
			}
			
			field.setAccessible(false);
		}
		catch(Exception e)
		{
			log.error(eField + eField.getAttribute("name"),e);
		}
	}
	
	@SuppressWarnings("unchecked")
	private void fillObjCollection(Element eField, Object obj, HashMap<String, Object> context)
	{
		try
		{
			PersistenceManager pm = PersistenceManager.getInstance();
			
			Strategy stg = PersistenceManager.getInstance().getStrategy(obj.getClass().getName());
			if(stg == null) return;
			
			boolean isValueFW = "yes".equals(stg.getFieldConfig(eField.getAttribute("name"), "value_flyweight"));

			Field field = PersistenceManager.getField(obj.getClass(), eField.getAttribute("name"));
			
			field.setAccessible(true);
			
			Object objField = field.get(obj);
			
			String strDimension = stg.getFieldConfig(field.getName(), "dimension");
			String strValueType = stg.getFieldConfig(field.getName(), "value_type");
			
			NodeList cellList = eField.getChildNodes();
			if(cellList == null || cellList.getLength() == 0) return;
			
			if(COLLECTION_TYPE_UNARY.equals(strDimension))	//一元容器
			{
				if(eField.getAttribute("class").indexOf("[") == -1)		//Collection
				{
					if(objField == null)
					{
						objField = Class.forName(eField.getAttribute("class")).newInstance();
						field.set(obj, objField);
					}
					
					Collection<Object> collection = (Collection<Object>)objField;
					//清空集合
					collection.clear();
					
					for(int i=0; i<cellList.getLength(); i++)
					{
						if(cellList.item(i).getNodeType() != Node.ELEMENT_NODE
								|| !cellList.item(i).getNodeName().equals("cell"))
								continue;
						
						Element eCell = (Element)cellList.item(i);
						
						//一元容器的value只允许出现primitive和complex
						if(FIELD_TYPE_PRIMITIVE.equals(strValueType))	//primitive value
						{
							Object objValue = this.createObject(
									eCell.getAttribute("class"),
									eCell.getAttribute("value"));
							/*Class<?> c = Class.forName(eCell.getAttribute("class"));
							if(c.isEnum())
							{
								Object [] enumValues = c.getEnumConstants();
								for(int j=0; j<enumValues.length; j++)
								{
									if(enumValues[j].toString().equals(eCell.getAttribute("value")))
									{
										objValue = enumValues[j];
										break;
									}
								}
							}
							else
							{
								Constructor<?> cst = c.getConstructor(java.lang.String.class);	//以String为参数的构造函数
								objValue = cst.newInstance(eCell.getAttribute("value"));
							}*/
							collection.add(objValue);
						}
						else if(FIELD_TYPE_COMPLEX.equals(strValueType))	//complex value
						{
							if(isValueFW)		//享元
							{
								String strValueClass = eCell.getAttribute("class");
								IFlyWeightManager fwm = pm.getFlyWeightManager(strValueClass);
								if(fwm != null)
								{
									String strFwId = eCell.getAttribute("objId");
									
									HashMap<String, Object> params = new HashMap<String, Object>();
									
									params.put("class", strValueClass);
									params.put("id", strFwId);
									
									Object objCell = fwm.getFlyWeight(params);
									collection.add(objCell);
								}
							}
							else				//非享元
							{
								NodeList objList = eCell.getChildNodes();
								
								if(objList != null && objList.getLength() > 0)
								{
									for(int k=0; k<objList.getLength(); k++)
									{
										if(objList.item(k).getNodeType() == Node.ELEMENT_NODE
												&& objList.item(k).getNodeName().equals("Object"))
										{
											Element eObj = (Element)objList.item(k);
											//TODO this.parse第一个参数填null未测试。by linyue
											collection.add(this.parse(null, eObj, context));
											break;
										}
									}
								}
							}
						}
					}
				}
				else											//数组
				{
					//重新生成数组
					int length = Integer.parseInt(eField.getAttribute("length"));
					
					Object objNewField = PersistenceManager.createArrayObject(
						field.getType().getName(),
						length);
					field.set(obj, objNewField);
					objField = objNewField;
					
					
					//赋值
					for(int i=0; i<cellList.getLength(); i++)
					{
						if(cellList.item(i).getNodeType() != Node.ELEMENT_NODE
								|| !cellList.item(i).getNodeName().equals("cell"))
								continue;
						
						Element eCell = (Element)cellList.item(i);
						
						String strCellClass = eCell.getAttribute("class");
						int index = Integer.parseInt(eCell.getAttribute("index"));
						
						//一元容器的value只允许出现primitive或complex
						if(FIELD_TYPE_PRIMITIVE.equals(strValueType))	//primitive value
						{
							String strCellValue = eCell.getAttribute("value");
							
							if("int".equals(strCellClass))
							{
								Array.setInt(objField, index, Integer.parseInt(strCellValue));
							}
							else if("char".equals(strCellClass))
							{
								Array.setChar(objField, index, strCellValue.charAt(0));
							}
							else if("byte".equals(strCellClass))
							{
								Array.setByte(objField, index, Byte.parseByte(strCellValue));
							}
							else if("short".equals(strCellClass))
							{
								Array.setShort(objField, index, Short.parseShort(strCellValue));
							}
							else if("long".equals(strCellClass))
							{
								Array.setLong(objField, index, Long.parseLong(strCellValue));
							}
							else if("float".equals(strCellClass))
							{
								Array.setFloat(objField, index, Float.parseFloat(strCellValue));
							}
							else if("double".equals(strCellClass))
							{
								Array.setDouble(objField, index, Double.parseDouble(strCellValue));
							}
							else if("boolean".equals(strCellClass))
							{
								Array.setBoolean(objField, index, Boolean.parseBoolean(strCellValue));
							}
							else
							{
								Object objValue = this.createObject(
									eCell.getAttribute("class"),
									eCell.getAttribute("value"));
								
								/*Class<?> c = Class.forName(strCellClass);
								Constructor<?> cst = c.getConstructor(java.lang.String.class);	//以String为参数的构造函数
								Object objValue = cst.newInstance(strCellValue);*/
									
								Array.set(objField, index, objValue);
							}
						}
						else if(FIELD_TYPE_COMPLEX.equals(strValueType))	//complex value
						{
							if(isValueFW)		//享元
							{
								String strValueClass = eCell.getAttribute("class");
								IFlyWeightManager fwm = pm.getFlyWeightManager(strValueClass);
								if(fwm != null)
								{
									String strFwId = eCell.getAttribute("objId");
									
									HashMap<String, Object> params = new HashMap<String, Object>();
									
									params.put("class", strValueClass);
									params.put("id", strFwId);
									
									Object objCell = fwm.getFlyWeight(params);
									Array.set(objField, index, objCell);
								}

							}
							else				//非享元
							{
								NodeList objList = eCell.getChildNodes();
								if(objList != null && objList.getLength() > 0)
								{
									for(int k=0; k<objList.getLength(); k++)
									{
										if(objList.item(k).getNodeType() == Node.ELEMENT_NODE
												&& objList.item(k).getNodeName().equals("Object"))
										{
											Element eObj = (Element)objList.item(k);
											//TODO this.parse第一个参数填null未测试。by linyue
											Array.set(objField, index, this.parse(null, eObj, context));
											
											break;
										}
									}
								}
							}
						}
						
					}
				}
			}
			else if(COLLECTION_TYPE_BINARY.equals(strDimension))	//二元容器
			{
				if(objField == null)
				{
					objField = Class.forName(eField.getAttribute("class")).newInstance();
					field.set(obj, objField);
				}
				
				String strKeyType = stg.getFieldConfig(field.getName(), "key_type");
				
				Map<Object, Object> map = (Map<Object, Object>)objField;
				//清空
				map.clear();
				
				for(int i=0; i<cellList.getLength(); i++)
				{
					if(cellList.item(i).getNodeType() != Node.ELEMENT_NODE
							|| !cellList.item(i).getNodeName().equals("cell"))
							continue;
					
					Element eCell = (Element)cellList.item(i);
					
					String strKeyClass = eCell.getAttribute("key_class");
					String strKey = eCell.getAttribute("key");
					if("".equals(strKeyClass)) continue;
					
					//二元容器的key只允许primitive
					if(FIELD_TYPE_PRIMITIVE.equals(strKeyType))
					{
						//二元容器的value只允许primitive和complex
						if(FIELD_TYPE_PRIMITIVE.equals(strValueType))	//primitive value
						{
							String strValueClass = eCell.getAttribute("value_class");
							String strValue = eCell.getAttribute("value");
							
							/*Class<?> cKey = Class.forName(strKeyClass);
							Constructor<?> cst = cKey.getConstructor(java.lang.String.class);	//参数为String的构造方法
							Object objKey = cst.newInstance(strKey);
							
							Class<?> cValue = Class.forName(strValueClass);
							cst = cValue.getConstructor(java.lang.String.class);	//参数为String的构造方法
							Object objValue = cst.newInstance(strValue);*/
							
							Object objKey = this.createObject(strKeyClass, strKey);
							Object objValue = this.createObject(strValueClass, strValue);
							
							map.put(objKey, objValue);
						}
						else if(FIELD_TYPE_COMPLEX.equals(strValueType))	//complex value
						{
							/*Class<?> cKey = Class.forName(strKeyClass);
							Constructor<?> cst = cKey.getConstructor(java.lang.String.class);	//参数为String的构造方法
							Object objKey = cst.newInstance(strKey);*/
							
							Object objKey = this.createObject(strKeyClass, strKey);
							
							if(isValueFW)		//享元
							{
								String strValueClass = eCell.getAttribute("value_class");
								IFlyWeightManager fwm = pm.getFlyWeightManager(strValueClass);
								if(fwm != null)
								{
									String strFwId = eCell.getAttribute("objId");
									
									HashMap<String, Object> params = new HashMap<String, Object>();
									
									params.put("class", strValueClass);
									params.put("id", strFwId);
									
									Object objCell = fwm.getFlyWeight(params);
									map.put(objKey, objCell);
								}
							}
							else				//非享元
							{
								NodeList objList = eCell.getChildNodes();
								
								boolean hasObj = false;
								
								for(int k=0; k<objList.getLength(); k++)
								{
									if(objList.item(k).getNodeType() == Node.ELEMENT_NODE
											&& objList.item(k).getNodeName().equals("Object"))
									{
											Element eObj = (Element)objList.item(k);
											//TODO this.parse第一个参数填null未测试。by linyue
											Object objValue = this.parse(null, eObj, context);
											map.put(objKey, objValue);
											
											hasObj = true;
											break;
									}
								}
								
								if(!hasObj)
								{
									map.put(objKey, null);
								}
							}
						}
					}
				}
			}
			
			field.setAccessible(false);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	private void fillObjComplex(Element eField, Object obj, HashMap<String, Object> context)
	{
		try
		{
			PersistenceManager pm = PersistenceManager.getInstance();
			
			Strategy stg = PersistenceManager.getInstance().getStrategy(obj.getClass().getName());
			if(stg == null) return;

			Field field = PersistenceManager.getField(obj.getClass(), eField.getAttribute("name"));
			field.setAccessible(true);
			
			boolean isFW = "yes".equals(stg.getFieldConfig(eField.getAttribute("name"), "flyweight"));
			if(isFW)		//享元
			{
				String strClass = eField.getAttribute("class");
				IFlyWeightManager fwm = pm.getFlyWeightManager(strClass);
				if(fwm != null)
				{
					String strFwId = eField.getAttribute("objId");
					
					HashMap<String, Object> params = new HashMap<String, Object>();
					
					params.put("class", strClass);
					params.put("id", strFwId);
					
					Object objField = fwm.getFlyWeight(params);
					field.set(obj, objField);
				}
			}
			else			//非享元
			{
				NodeList objList = eField.getChildNodes();
				for(int k=0; k<objList.getLength(); k++)
				{
					if(objList.item(k).getNodeType() == Node.ELEMENT_NODE
							&& objList.item(k).getNodeName().equals("Object"))
					{
						Element eObj = (Element)objList.item(k);
						//TODO this.parse第一个参数填null未测试。by linyue
						Object objField = this.parse(null, eObj, context);
						field.set(obj, objField);
						break;
					}	
				}
			}
			
			field.setAccessible(false);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	
	/**
	 * 用给定XML数据填充对象
	 * @param data			XML数据
	 * @param obj			待填充对象
	 * @param context		上下文环境
	 */
	private void fillObj(Element data, Object obj, HashMap<String, Object> context)
	{
		Strategy stg = PersistenceManager.getInstance().getStrategy(data.getAttribute("class"));
		if(stg == null) return;
		
		if(!stg.isStrictOrder)
		{
			NodeList fieldList = data.getChildNodes();

			for(int i=0; i<fieldList.getLength(); i++)
			{
				if(fieldList.item(i).getNodeType() != Node.ELEMENT_NODE
						|| !fieldList.item(i).getNodeName().equals("Field")) continue;
				Element eField = (Element)fieldList.item(i);
				
				String type = stg.getFieldConfig(eField.getAttribute("name"), "type");
				if(FIELD_TYPE_PRIMITIVE.equals(type))
				{
					this.fillObjPrimitive(eField, obj, context);
				}
				else if(FIELD_TYPE_COLLECTION.equals(type))
				{
					this.fillObjCollection(eField, obj, context);
				}
				else if(FIELD_TYPE_COMPLEX.equals(type))
				{
					this.fillObjComplex(eField, obj, context);
				}
			}
		}
		else		//需要保证严格的读取顺序
		{
			String [] fields = stg.getFields();
			
			for(int j=0; j<fields.length; j++)
			{
				NodeList fieldList = data.getChildNodes();

				for(int i=0; i<fieldList.getLength(); i++)
				{
					if(fieldList.item(i).getNodeType() != Node.ELEMENT_NODE
							|| !fieldList.item(i).getNodeName().equals("Field")) continue;
					Element eField = (Element)fieldList.item(i);
					
					if(eField.getAttribute("name").equals(fields[j]))
					{
						String type = stg.getFieldConfig(eField.getAttribute("name"), "type");
						if(FIELD_TYPE_PRIMITIVE.equals(type))
						{
							this.fillObjPrimitive(eField, obj, context);
						}
						else if(FIELD_TYPE_COLLECTION.equals(type))
						{
							this.fillObjCollection(eField, obj, context);
						}
						else if(FIELD_TYPE_COMPLEX.equals(type))
						{
							this.fillObjComplex(eField, obj, context);
						}
						break;
					}
				}
				
			}
		}
	}
	
}
